import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, CreateAxiosDefaults } from 'axios'

import { encrypt } from './encrypt'
import { LoginUser } from '@/api/login/type'

class http {
  constructor() {}

  static create(config: CreateAxiosDefaults<any>): AxiosInstance {
    const httpService = axios.create(config)
    const cancelToken = axios.CancelToken

    const source = cancelToken.source()

    httpService.interceptors.response.use(
      (response: AxiosResponse) => {
        switch (response.data.code) {
          case process.env.VITE_APP_MAGIC_VAL:
            return response.data.data
          case '9998':
            alert('鉴权信息格式有误, 请检查')
            break
          case '9990':
          case '9991':
          case '9992':
          case '9994':
          case '9996':
          case '9997':
          case '9999':
            sessionStorage.clear()
            window.location.href =
              window.location.protocol +
              '//' +
              window.location.hostname +
              (window.location.port ? ':' + window.location.port : '') +
              process.env.VITE_APP_CONTEXT_PATH
            return Promise.reject(response.data.message || 'Error')
          default:
            return Promise.reject(response.data.message || 'Error')
        }
      },
      (error: any) => {
        return Promise.reject(error)
      }
    )

    httpService.interceptors.request.use(
      (request) => {
        if (request.url?.includes('/api/login/doLogin')) {
          return request
        }
        if (window.sessionStorage.getItem('loginUser') === null) {
          request.cancelToken = source.token
          source.cancel('Operation canceled by the user.')
        } else {
          const currentUser: LoginUser = JSON.parse(window.sessionStorage.getItem('loginUser')!)
          request.headers['Cache-Control'] = 'no-cache'
          request.headers['Authorization'] = encrypt.auth(request)
          request.headers[currentUser.tokenName] = currentUser.token
        }
        return request
      },
      (error) => {
        console.log('http error: ', error)

        return Promise.reject(error)
      }
    )
    return httpService
  }
}

export { http }
